#include "rtp.h"
#include<WinSock2.h>
#include<WS2tcpip.h>
#pragma warning( disable : 4996 ) // inet_addr 方法已经被遗弃了，直接调用会报错，需要禁用该报错

void rtpHeaderInit(RtpPacket* rtpPacket, uint8_t version, uint8_t padding, uint8_t extension, uint8_t csrcLen, uint8_t marker, uint8_t payloadType, uint16_t seq, uint32_t timestamp, uint32_t ssrc)
{
    rtpPacket->rtpHeader.version = version;
    rtpPacket->rtpHeader.padding = padding;
    rtpPacket->rtpHeader.extension = extension;
    rtpPacket->rtpHeader.csrcLen = csrcLen;
    rtpPacket->rtpHeader.marker = marker;
    rtpPacket->rtpHeader.payloadType = payloadType;
    rtpPacket->rtpHeader.seq = seq;
    rtpPacket->rtpHeader.timestamp = timestamp;
    rtpPacket->rtpHeader.ssrc = ssrc;
}

int rtpSendPacketOverTcp(int clientSockfd, RtpPacket* rtpPacket, uint32_t dataSize)
{
    // 主机序转换为网络序[大于1个字节的数据才需要转换]
    rtpPacket->rtpHeader.seq = htons(rtpPacket->rtpHeader.seq);
    rtpPacket->rtpHeader.timestamp = htonl(rtpPacket->rtpHeader.timestamp);
    rtpPacket->rtpHeader.ssrc = htonl(rtpPacket->rtpHeader.ssrc);

    uint32_t rtpSize = RTP_HEADER_SIZE + dataSize;
    char* tempBuf = (char*)malloc(4 + rtpSize);
    // vs的warn提醒
    if (!tempBuf)
    {
        return -1;
    }
    // 而外加了前四个字节好像为了是区分TCP中RTP包的？目前没看过，后续再看
    tempBuf[0] = 0x24; // $ 起始符号
    tempBuf[1] = 0x00; // 0 一般是rtp的channel
    tempBuf[2] = (uint8_t)(((rtpSize) & 0xFF00) >> 8);
    tempBuf[3] = (uint8_t)((rtpSize) & 0xFF);
    memcpy(tempBuf + 4, (char*)rtpPacket, rtpSize);

    // 发送TCP数据
    int ret = send(clientSockfd, tempBuf, 4 + rtpSize, 0);
    // 将网络序重新转换为主机序[因为等会还要拿这个数据计算]
    rtpPacket->rtpHeader.seq = ntohs(rtpPacket->rtpHeader.seq);
    rtpPacket->rtpHeader.timestamp = ntohl(rtpPacket->rtpHeader.timestamp);
    rtpPacket->rtpHeader.ssrc = ntohl(rtpPacket->rtpHeader.ssrc);

    free(tempBuf);
    tempBuf = NULL;

    return ret;
}

int rtpSendPacketOverUdp(int serverRtpSockfd, const char* ip, int16_t port, RtpPacket* rtpPacket, uint32_t dataSize)
{
    // 主机序转换为网络序[大于1个字节的数据才需要转换]
    rtpPacket->rtpHeader.seq = htons(rtpPacket->rtpHeader.seq);
    rtpPacket->rtpHeader.timestamp = htonl(rtpPacket->rtpHeader.timestamp);
    rtpPacket->rtpHeader.ssrc = htonl(rtpPacket->rtpHeader.ssrc);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    // 发送UDP数据
    int ret = sendto(serverRtpSockfd, (char*)rtpPacket, dataSize + RTP_HEADER_SIZE, 0,
                    (struct sockaddr*)&addr, sizeof(addr));

    // 将网络序重新转换为主机序[因为等会还要拿这个数据计算]
    rtpPacket->rtpHeader.seq = ntohs(rtpPacket->rtpHeader.seq);
    rtpPacket->rtpHeader.timestamp = ntohl(rtpPacket->rtpHeader.timestamp);
    rtpPacket->rtpHeader.ssrc = ntohl(rtpPacket->rtpHeader.ssrc);

	return ret;
}
